import Vue from "vue";
import store from "@/store";
import router from "@/router";
// 判断是否函数
function isFunction(value) {
  return typeof value === "function";
}

/**
 * 调用自定义hook
 * @param vm 实例对象
 * @param { String } hook hook name
 * @param { * } args hook 参数
 */
const callHook = (vm, hook, ...args) => vm.$options?.[hook]?.apply(vm, args);

/**
 * 动态创建组件
 * @param { Function } options.ctor 异步组件
 * @param { Object } options.props 组件参数
 * @param { Object } options.on 组件事件
 * @param { Function } options.children 子组件
 * @returns {Promise<Vue|(object & Record<never, any> & Vue)|VNode>}
 * @constructor
 */
const createPopup = async function (options) {
  // 生成的组件实例
  const { ctor, props, on, children } = options;
  const _ctor = isFunction(ctor) ? (await ctor()).default : ctor;
  const _children = isFunction(children) ? (await children()).default : children;
  const instance = new Vue({
    store,
    router,
    render(h) {
      const _on = { ...on, destroy: this.onDestroy };
      return h(_ctor, { ref: "ctor", on: _on, props }, [
        _children ? h(_children, { ref: "children", on: _on, props }) : null,
      ]);
    },
    destroyed() {
      document.body.removeChild(instance.$el);
    },
    methods: {
      onDestroy() {
        const next = (delay) => setTimeout(() => this.$destroy(), delay || 0);
        callHook(instance.$refs.ctor, "unCreateApi", next);
      },
    },
  });
  instance.$mount();
  callHook(instance.$refs.ctor, "onCreateApi");
  document.body.appendChild(instance.$el);
  return instance;
};

export default createPopup;
